package com.gengzp.common.document.core.impl;

import com.gengzp.common.document.annotations.Api;
import com.gengzp.common.document.annotations.ApiModel;
import com.gengzp.common.document.core.DocumentAnnotationReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @ClassName DocumentAnnotationsReaderImpl
 * @Description 文档注解读取器实现类
 * @Author gengzp
 * @Date 2025/5/21 0:42
 */
@Component
public class DocumentAnnotationReaderImpl implements DocumentAnnotationReader {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public List<Object> searchAllControllerClass() {
        return applicationContext.getBeansWithAnnotation(Api.class).values().stream().toList();
    }

    @Override
    public String getMappingAnnotationUrlFromMethod(Method method) {
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping != null) {
            return requestMapping.value()[0];
        }
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if (getMapping != null) {
            return getMapping.value()[0];
        }
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if (postMapping != null) {
            return postMapping.value()[0];
        }
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if (putMapping != null) {
            return putMapping.value()[0];
        }
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if (deleteMapping != null) {
            return deleteMapping.value()[0];
        }
        return null;
    }

    @Override
    public String getMethodRequestType(Method method) {
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if (getMapping != null) {
            return "GET";
        }
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if (postMapping != null) {
            return "POST";
        }
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if (putMapping != null) {
            return "PUT";
        }
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if (deleteMapping != null) {
            return "DELETE";
        }
        return null;
    }

    @Override
    public Method getMethodByUrl(String controllerUrl, String methodUrl) {
        List<Object> objects = searchAllControllerClass();
        if (objects == null || objects.isEmpty()) {
            return null;
        }

        // 根据 controllerUrl 取出控制器bean
        Object controllerBean = objects.stream()
                .filter(v -> controllerUrl.equals(v.getClass().getAnnotation(RequestMapping.class).value()[0]))
                .findFirst().orElse(null);
        if (controllerBean == null) {
            return null;
        }

        // 取出要查询的控制器中的方法
        return Arrays.stream(controllerBean.getClass().getDeclaredMethods())
                .filter(v -> methodUrl.equals(getMappingAnnotationUrlFromMethod(v)))
                .findFirst().orElse(null);
    }

    @Override
    public String getParamDescription(Class<?> bean) {
        return bean.getAnnotation(ApiModel.class).description();
    }

}
